﻿#ifndef __AF_PACKAGE_H__
#define __AF_PACKAGE_H__

namespace AF
{
	class Package;
}
typedef AF::Package			AF_CPackage;

#include "AF_Image.h"
#include "AF_Struct.h"

/// 磁盘目录资源类型
#define AF_PKG_DISK			"_Disk"

namespace AF
{
	/// 资源包基类
	class Package
	{
	public:
		/// 创建或获得指定类型资源包
		template<class AF_PKGTYPE>
		static Package*		GetPackage(const _STRING strPathName, const _STRING strType = AF_PKG_DISK);
		/// 创建或获得默认类型资源包
		static Package*		GetDefaultPackage(const _STRING strPathName);
		/// 销毁指定资源包
		static bool		DestroyOne(const _STRING strPathName);
		/// 销毁所有资源包
		static bool		DestroyAll();

	private:
		static Table<Package*>	PackageTable;

	public:
		Package();
		virtual ~Package();

	public:
		/// 加载资源包
		bool			Load(const _STRING strPathName, const _STRING strKind = AF_PKG_DISK);
		/// 获得资源包内的图像句柄
		ImageHandle		GetImageHandle(
						const _STRING strImageName,
						UINT& _OUT nWidth,
						UINT& _OUT nHeight,
						ImageInfo& _OUT ii
					);
		/// 获得资源包内的图像
		Image*			GetImage(const _STRING strImageName);
//		UINT			GetData(const char szResName, BYTE* bData);
		/// 清除资源包
		bool			Release();
	
		/// 获得资源包所打开的路径
		_STRING			GetPathName();
		/// 获得资源包类型
		_STRING			GetKind();

	public:
		/// 获得资源数量
		virtual int		GetCount();

	protected:
		/// 当加载资源包时
		virtual bool		OnLoad(const _STRING strPathName)
					{return false;}
		/// 当清除资源包时
		virtual bool		OnRelease()
					{return false;}
		/// 当读取资源包内的图像句柄时
		virtual ImageHandle	OnLoadImageHandle(
						const _STRING strImageName,
						UINT& _OUT nWidth,
						UINT& _OUT nHeight,
						ImageInfo& _OUT ii
					);
		/// 当销毁图像句柄时
		virtual bool		OnDestroyImageHandle(ImageHandle hImage);

	protected:
		/// 资源包路径
		_STRING			m_strPath;
		/// 资源包类型
		_STRING			m_strKind;
		/// 资源数
		int			m_nResCount;
		/// 资源包内图像句柄表
		Table<ImageHandle>	m_tabImageHandles;
	};

	template<class AF_PKGTYPE>
	Package* Package::GetPackage(const _STRING strPathName, const _STRING strType)
	{
		AF_CHECK_R(strType.size() != 0, NULL);

		Package* _pPackage = NULL;
		_pPackage = PackageTable.Get(strPathName);

		if(_pPackage == NULL)
		{
			AF_CHECK_R(strPathName != "", NULL);

			_pPackage = AF_NEW(AF_PKGTYPE);

			if(!_pPackage->Load(strPathName, strType))
				return NULL;

			PackageTable.Put(strPathName, _pPackage);
		}

		return _pPackage;
	}
}

#endif